/**
 * 视图组件 - ECS 实体与 Cocos Creator 节点的桥接
 * 
 * 职责：
 * 1. 存储 Cocos Creator 节点引用
 * 2. 按需懒加载缓存组件引用
 * 3. 管理节点的生命周期
 * 
 * 设计：
 * - 使用懒加载（Lazy Loading）策略
 * - 只在第一次访问时缓存组件
 * - 避免缓存不需要的组件
 * 
 * 性能优势：
 * - 初始化开销：0 μs（无预缓存）
 * - 首次访问：+2-5 μs（getComponent）
 * - 后续访问：~2-5 ns（直接引用）
 * 
 * 注意：canNew 设置为 false，因为包含 Cocos 引擎对象
 * 
 * @author AI Assistant
 * @date 2025-11-29
 */

import { ecs } from "../../../core/ecs/ECS";
import { Node, Sprite, Label, Animation, UITransform, RigidBody2D, Collider2D, Component } from "cc";

/**
 * 视图组件类型枚举
 */
export enum ViewComponentType {
    /** 2D 渲染组件（Sprite, Label） */
    RENDER_2D = 'render2d',
    /** UI 组件（UITransform） */
    UI = 'ui',
    /** 动画组件（Animation） */
    ANIMATION = 'animation',
    /** 物理组件（RigidBody2D, Collider2D） */
    PHYSICS = 'physics',
    /** 自定义组件 */
    CUSTOM = 'custom'
}

/**
 * 视图组件类 - 基础版（已废弃）
 * 
 * @deprecated 请使用 ViewComponentFull 代替
 * 
 * 此文件保留仅用于向后兼容。
 * 新项目请使用 view/ 目录下的专用组件。
 * 
 * 将 Cocos Creator 节点绑定到 ECS 实体
 * 
 * 所有引擎组件使用懒加载策略，按需缓存
 */
@ecs.register('ViewLegacy', false) // 修改注册名避免与 ViewComponentFull 冲突
export class ViewComponent extends ecs.Comp {
    // ========== 核心引用 ==========
    
    /** 根节点引用 */
    public node: Node | null = null;
    
    // ========== 懒加载缓存（使用 undefined 表示未初始化）==========
    
    /** Sprite 组件（图片渲染）- 懒加载 */
    private _sprite: Sprite | null | undefined = undefined;
    
    /** Label 组件（文本渲染）- 懒加载 */
    private _label: Label | null | undefined = undefined;
    
    /** Animation 组件（动画播放）- 懒加载 */
    private _animation: Animation | null | undefined = undefined;
    
    /** UITransform 组件（UI 变换）- 懒加载 */
    private _uiTransform: UITransform | null | undefined = undefined;
    
    /** RigidBody2D 组件（2D 物理刚体）- 懒加载 */
    private _rigidbody: RigidBody2D | null | undefined = undefined;
    
    /** Collider2D 组件（2D 碰撞器）- 懒加载 */
    private _collider: Collider2D | null | undefined = undefined;
    
    // ========== 状态标记 ==========
    
    /** 是否已准备好 */
    public isReady: boolean = false;
    
    /** 是否可见 */
    public isVisible: boolean = true;
    
    /** 层级名称（用于调试） */
    public layerName: string = '';
    
    /** 组件类型标记（用于优化查询） */
    public componentTypes: Set<ViewComponentType> = new Set();
    
    // ========== 自定义组件缓存 ==========
    
    /** 自定义组件缓存（通过类型访问） */
    private customComponents: Map<any, Component> = new Map();
    
    // ========== 懒加载 Getter ==========
    
    /**
     * 获取 Sprite 组件（懒加载）
     */
    get sprite(): Sprite | null {
        if (this._sprite === undefined) {
            this._sprite = this.node?.getComponent(Sprite) || null;
            if (this._sprite) {
                this.componentTypes.add(ViewComponentType.RENDER_2D);
            }
        }
        return this._sprite;
    }
    
    /**
     * 获取 Label 组件（懒加载）
     */
    get label(): Label | null {
        if (this._label === undefined) {
            this._label = this.node?.getComponent(Label) || null;
            if (this._label) {
                this.componentTypes.add(ViewComponentType.RENDER_2D);
            }
        }
        return this._label;
    }
    
    /**
     * 获取 Animation 组件（懒加载）
     */
    get animation(): Animation | null {
        if (this._animation === undefined) {
            this._animation = this.node?.getComponent(Animation) || null;
            if (this._animation) {
                this.componentTypes.add(ViewComponentType.ANIMATION);
            }
        }
        return this._animation;
    }
    
    /**
     * 获取 UITransform 组件（懒加载）
     */
    get uiTransform(): UITransform | null {
        if (this._uiTransform === undefined) {
            this._uiTransform = this.node?.getComponent(UITransform) || null;
            if (this._uiTransform) {
                this.componentTypes.add(ViewComponentType.UI);
            }
        }
        return this._uiTransform;
    }
    
    /**
     * 获取 RigidBody2D 组件（懒加载）
     */
    get rigidbody(): RigidBody2D | null {
        if (this._rigidbody === undefined) {
            this._rigidbody = this.node?.getComponent(RigidBody2D) || null;
            if (this._rigidbody) {
                this.componentTypes.add(ViewComponentType.PHYSICS);
            }
        }
        return this._rigidbody;
    }
    
    /**
     * 获取 Collider2D 组件（懒加载）
     */
    get collider(): Collider2D | null {
        if (this._collider === undefined) {
            this._collider = this.node?.getComponent(Collider2D) || null;
            if (this._collider) {
                this.componentTypes.add(ViewComponentType.PHYSICS);
            }
        }
        return this._collider;
    }
    
    /**
     * 重置组件
     */
    reset(): void {
        this.node = null;
        
        // 重置懒加载缓存
        this._sprite = undefined;
        this._label = undefined;
        this._animation = undefined;
        this._uiTransform = undefined;
        this._rigidbody = undefined;
        this._collider = undefined;
        
        this.isReady = false;
        this.isVisible = true;
        this.layerName = '';
        this.componentTypes.clear();
        this.customComponents.clear();
    }
    
    /**
     * 初始化视图组件
     * @param node Cocos Creator 节点
     */
    init(node: Node): void {
        if (!node || !node.isValid) {
            console.error('[ViewComponent] 无效的节点');
            return;
        }
        
        this.node = node;
        this.isReady = true;
        this.isVisible = node.active;
        
        // 不再预缓存，所有组件按需懒加载
        console.log(`[ViewComponent] 初始化完成: ${node.name} (懒加载模式)`);
    }
    
    /**
     * 获取自定义组件（通过类型，推荐使用）
     * @param componentType 组件类型
     * @returns 组件实例，不存在则返回 null
     * 
     * @example
     * const myComp = view.getCustomComponent(MyCustomComponent);
     */
    getCustomComponent<T extends Component>(componentType: new () => T): T | null {
        if (!this.node) return null;
        
        // 检查缓存
        if (this.customComponents.has(componentType)) {
            return this.customComponents.get(componentType) as T;
        }
        
        // 获取组件并缓存
        const component = this.node.getComponent(componentType);
        if (component) {
            this.customComponents.set(componentType, component);
            this.componentTypes.add(ViewComponentType.CUSTOM);
            return component as T;
        }
        
        return null;
    }
    
    /**
     * 获取自定义组件（通过类名，兼容旧代码）
     * @param componentName 组件类名
     * @returns 组件实例，不存在则返回 null
     * 
     * @deprecated 推荐使用类型安全的 getCustomComponent(Type) 方法
     */
    getCustomComponentByName<T = any>(componentName: string): T | null {
        if (!this.node) return null;
        
        // 获取组件（不缓存，因为字符串查找不可靠）
        const component = this.node.getComponent(componentName);
        return component as T || null;
    }
    
    /**
     * 检查是否有指定类型的组件
     * @param type 组件类型
     */
    hasComponentType(type: ViewComponentType): boolean {
        return this.componentTypes.has(type);
    }
    
    /**
     * 预加载指定类型的组件（用于性能优化）
     * @param types 要预加载的组件类型
     * 
     * @example
     * // 如果你确定需要这些组件，可以预加载
     * view.preloadComponents([ViewComponentType.RENDER_2D, ViewComponentType.UI]);
     */
    preloadComponents(types: ViewComponentType[]): void {
        if (!this.node) return;
        
        for (const type of types) {
            switch (type) {
                case ViewComponentType.RENDER_2D:
                    // 触发 getter，自动缓存
                    this.sprite;
                    this.label;
                    break;
                case ViewComponentType.UI:
                    this.uiTransform;
                    break;
                case ViewComponentType.ANIMATION:
                    this.animation;
                    break;
                case ViewComponentType.PHYSICS:
                    this.rigidbody;
                    this.collider;
                    break;
            }
        }
    }
    
    /**
     * 设置可见性
     * @param visible 是否可见
     */
    setVisible(visible: boolean): void {
        if (!this.node || !this.node.isValid) return;
        
        this.node.active = visible;
        this.isVisible = visible;
    }
    
    /**
     * 切换可见性
     */
    toggleVisible(): void {
        this.setVisible(!this.isVisible);
    }
    
    /**
     * 播放动画
     * @param animName 动画名称
     * @param loop 是否循环（默认 false）
     */
    playAnimation(animName: string, loop: boolean = false): void {
        if (!this.animation) {
            console.warn('[ViewComponent] 没有 Animation 组件');
            return;
        }
        
        const animState = this.animation.getState(animName);
        if (animState) {
            // 设置循环模式
            if (loop) {
                animState.wrapMode = 2; // Loop
            } else {
                animState.wrapMode = 1; // Normal
            }
            this.animation.play(animName);
        } else {
            console.warn(`[ViewComponent] 动画 "${animName}" 不存在`);
        }
    }
    
    /**
     * 停止动画
     */
    stopAnimation(): void {
        if (this.animation) {
            this.animation.stop();
        }
    }
    
    /**
     * 销毁节点
     * @param immediate 是否立即销毁（默认 false）
     */
    destroyNode(immediate: boolean = false): void {
        if (!this.node || !this.node.isValid) return;
        
        const nodeName = this.node.name;
        
        if (immediate) {
            this.node.destroyAllChildren();
            this.node.destroy();
        } else {
            this.node.destroy();
        }
        
        console.log(`[ViewComponent] 销毁节点: ${nodeName}`);
        
        this.reset();
    }
    
    /**
     * 检查节点是否有效
     */
    isValid(): boolean {
        return this.node !== null && this.node.isValid;
    }
    
    /**
     * 获取节点名称（用于调试）
     */
    getNodeName(): string {
        return this.node ? this.node.name : '<无节点>';
    }
    
    /**
     * 获取节点路径（用于调试）
     */
    getNodePath(): string {
        if (!this.node) return '<无节点>';
        
        let path = this.node.name;
        let parent = this.node.parent;
        
        while (parent) {
            path = `${parent.name}/${path}`;
            parent = parent.parent;
        }
        
        return path;
    }
}

